home *** CD-ROM | disk | FTP | other *** search
/ TeX 1995 July / TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO / tex-k / tex-k-archive.past / tex-k-archive.gz / tex-k-archive / 000119_magnan@mathcn.umontreal.ca_Wed Dec 15 05:08:25 1993.msg < prev    next >
Internet Message Format  |  1994-10-11  |  17KB

  1. Received: from condor.CC.UMontreal.CA by cs.umb.edu with SMTP id AA03177
  2.   (5.65c/IDA-1.4.4 for <tex-k@cs.umb.edu>); Wed, 15 Dec 1993 10:11:47 -0500
  3. Received: from maths1.MATHCN.UMontreal.CA by condor.CC.UMontreal.CA with SMTP id AA00987
  4.   (5.65c/IDA-1.4.4 for tex-k@cs.umb.edu); Wed, 15 Dec 1993 10:09:24 -0500
  5. Received: by maths1.MATHCN.UMontreal.CA (930416.SGI/5.17)
  6.     id AA09811; Wed, 15 Dec 93 10:08:25 -0500
  7. Date: Wed, 15 Dec 93 10:08:25 -0500
  8. From: magnan@mathcn.umontreal.ca (Magnan Francois)
  9. Message-Id: <9312151508.AA09811@maths1.MATHCN.UMontreal.CA>
  10. To: Martyn.Johnson@cl.cam.ac.uk
  11. Cc: tex-k@cs.umb.edu, Martyn.Johnson@cl.cam.ac.uk
  12. In-Reply-To: <"swan.cl.cam.:198520:931215085340"@cl.cam.ac.uk> (message from Martyn Johnson on Wed, 15 Dec 1993 08:52:04 +0000)
  13. Subject: Re: xdvik
  14.  
  15.  
  16. It seem that many applications (postscript drawing programs) add a 
  17. ".00" after the numbers. I fixed it by changing the parsing routines
  18. so they take care of both possibilities. Here is my epsf.c file
  19.  
  20. /*
  21.  * Drawing routine for \special commands generated
  22.  * by epsf.sty and epsf.tex, i.e., of the form:
  23.  *   psfile=/u11/doug/foo.ps llx=165 lly=346 urx=461 ury=434 rwi=2663
  24.  *
  25.  * No Copyright.  Public domain.
  26.  * Doug Bryan, dbryan@stanford.edu, January 1993. 
  27.  *
  28.  * History:
  29.  *  06/07/93: Support for psfig added
  30.  *            Case sensitivity of the PSfile= flag removed
  31.  *            Norm Walsh, walsh@cs.umass.edu
  32.  *  08/30/93: Changed include file "xdvi.h" to "config.h" so
  33.  *            that it will work with xdvik.
  34.  *            Alan DeWeerd, deweerd@wisnuf.physics.wisc.edu
  35.  *
  36.  * Compilation options:
  37.  *      MSBITFIRST store bitmaps internally with most significant bit firs-
  38.  *      BMSHORT store bitmaps in shorts instead of bytes
  39.  *      BMLONG  store bitmaps in longs instead of bytes
  40.  *      GSEXEC  the executable for the ghostscript interpreter, e.g., "gs"
  41.  *
  42.  * It'd be way cool to someday do greyscale anti-aliasing on the bitmaps
  43.  * gs generates, and then display the pixmap.
  44.  */
  45.  
  46. #include "config.h"
  47. #include <kpathsea/c-stat.h>
  48. #include <kpathsea/filefmt.h>
  49. #include <kpathsea/pathsearch.h>
  50.  
  51. #include "epsf.h"
  52. extern void put_grey_rectangle ();
  53.  
  54. #ifndef L_tmpnam
  55. #define L_tmpnam 256
  56. #endif
  57. #ifndef GSEXEC
  58. #define GSEXEC "gs2"
  59. #endif
  60. #define XMALLOC_LABEL "gs bitmap"
  61. #define    RESOLUTION  (pixels_per_inch/shrink_factor)
  62.   /* current pixels per inch */
  63. #define FRESOLUTION ((float)RESOLUTION)
  64. #define PT2PXL(x) ((int)((float)(x) * FRESOLUTION / 72.0))
  65.   /* convert points (i.e., 1/72 inches) to pixels */
  66.  
  67. /*
  68.  * Print error message.
  69.  */
  70. static void
  71. Moan(fmt, msg)
  72.   char    *fmt, *msg;
  73. {
  74.   if (!hush_spec_now) {
  75.     Fprintf(stderr, "%s: espf: ", prog);
  76.     Fprintf(stderr, fmt, msg);
  77.     (void) fputc('\n', stderr);
  78.   }
  79. }
  80.  
  81. /* Parsing routines from  labrea.Stanford.EDU:~ftp/pub/tv001.tar.Z */
  82.  
  83. static char *getkeyword(p)
  84. register char *p ;
  85. {
  86.    while (*p && *p != '=')
  87.       p++ ;
  88.    if (*p) {
  89.       *p = 0 ;
  90.       return p + 1 ;
  91.    } else
  92.       return 0 ;
  93. }
  94.  
  95. static int getint(p, q)
  96. register char *p ;
  97. char **q ;
  98. {
  99.    int negative = 0 ;
  100.    register int div = 0 ;
  101.    register int accum = 0 ;
  102.  
  103.    while (*p <= ' ' && *p)
  104.       p++ ;
  105.    if (*p == '-') {
  106.       negative = 1 ;
  107.       p++ ;
  108.    }
  109.    while ('0' <= *p && *p <= '9') {
  110.          accum = accum * 10 + (*p - '0') ;
  111.      p++; }
  112.  
  113.    while (*p != ' ' && *p)
  114.       p++ ;
  115.    while (*p <= ' ' && *p)
  116.       p++ ;
  117.    *q = p ;
  118.    if (div > 0.1)
  119.       accum = accum / div ;
  120.    if (negative)
  121.       return -accum ;
  122.    else
  123.       return accum ;
  124. }
  125.  
  126.  
  127. /* Modified with labrea.Stanford.EDU:~ftp/pub/tv001.tar.Z parsing */
  128. /* routines. This is an attempted fix. Not very clean code!!!     */
  129. /* F.Magnan magnan@mathcn.umontreal.ca */
  130.  
  131. static Boolean
  132. parse_special(special, psfilename, llx, lly, urx, ury, rwi)
  133.   char *special, *psfilename;
  134.   int *llx, *lly, *urx, *ury, *rwi;
  135. {
  136.   int t;
  137.   char *pp,*q;
  138.  
  139.   special += 6; /* skip the ``psfile'' which may be case-mixed */
  140.   sscanf(special,"=%s ",psfilename);
  141.   while (q = getkeyword(special)) {
  142.       pp = special ;
  143.       t = getint(q, &special) ;
  144.       if (strncmp(pp, "llx", 3)==0)
  145.          *llx = t ; 
  146.       else if (strncmp(pp, "lly", 3)==0)
  147.          *lly = t ; 
  148.       else if (strncmp(pp, "urx", 3)==0)
  149.          *urx = t ; 
  150.       else if (strncmp(pp, "ury", 3)==0)
  151.          *ury = t ; 
  152.       else if (strncmp(pp, "rwi", 3)==0)
  153.          *rwi = t ;
  154.    } 
  155.   return True;
  156. }
  157.  
  158. /*
  159.  * Simple sscanf version of finding psfig \special parameters.
  160.  */
  161. static Boolean
  162. parse_psfig_special(special, width, height, llx, lly, urx, ury, rwi)
  163.   char *special;
  164.   int *width, *height, *llx, *lly, *urx, *ury, *rwi;
  165. {
  166.   if (sscanf(special, "ps::[begin] %d %d %d %d %d %d",
  167.               width, height, llx, lly, urx, ury) == 6) {
  168.     return True;
  169.   } else {
  170.     Moan("\"%s\" not understood.", special);
  171.     return False;
  172.   }
  173. }
  174.  
  175. struct cache_node {
  176.   char   *filename;
  177.   time_t mtime;
  178.   float  scale;
  179.   int    resolution;
  180.   struct bitmap *bm;
  181.   struct cache_node *next;
  182. };
  183.  
  184. static struct cache_node *cache = NULL;
  185. /* 
  186.  * Cache bitmaps so we don't call gs so much.  Actully, epsfile() is
  187.  * called way too much.  xdvi should use backing store and let X11 do
  188.  * the caching.  Oh well.  On a 30MIP machine who cares?
  189.  */
  190.  
  191. static time_t 
  192. mod_time_of(filename)
  193.   char *filename;
  194. {
  195.   struct stat stat_buff;
  196.  
  197.   if (stat(filename, &stat_buff)==0) {
  198.     return stat_buff.st_mtime;
  199.   } else {
  200.     return 0;
  201.   }
  202. }
  203.  
  204. /*
  205.  * Free one item in the cache.
  206.  * Could be clever and flush the one with the highest
  207.  * resolution, or biggest bitmap, or...
  208.  */
  209. void flush_one_gsbm()
  210. {
  211.   struct cache_node *head = cache;
  212.  
  213.   if (head) {
  214.     cache = cache->next;
  215.     free(head->filename);
  216.     free(head->bm->bits);
  217.     free(head->bm);
  218.     free(head);
  219.   }
  220. }
  221.  
  222. /* 
  223.  * Free all items in the cache.
  224.  */
  225. void flush_gsbm_cache()
  226. {
  227.   while (cache) flush_one_gsbm();
  228. }
  229.  
  230. /*
  231.  * Try to find a bitmap for psfname, at the given scale and res, in the cache. 
  232.  */
  233. static struct bitmap *
  234. find_bitmap(psfname, x_scale, y_scale, res)
  235.   char  *psfname;
  236.   float x_scale, y_scale;
  237.   int   res;
  238. {
  239.   struct cache_node *ll, *pred;
  240.  
  241.   for (ll=cache, pred=NULL;  ll;  pred=ll, ll=ll->next) {
  242.     if (ll->resolution==res && ll->scale==x_scale &&
  243.     strcmp(ll->filename, psfname)==0) {    
  244.       if (mod_time_of(psfname) == ll->mtime) {
  245.     return ll->bm;
  246.       } else {
  247.     /* File has been modified.  Remove it from cache. */
  248.     if (!pred) {
  249.       cache = cache->next;
  250.     } else {
  251.       pred->next = ll->next;
  252.     }
  253.     free(ll->filename);
  254.     free(ll->bm->bits);
  255.     free(ll->bm);
  256.     free(ll);
  257.     return NULL;
  258.       }
  259.     }
  260.   }
  261.   return NULL;
  262. }
  263.  
  264. /*
  265.  * Find a bitmap for psfname at the given scale and current resolution.
  266.  * Get it from the cache, or generate it using ghostscript.
  267.  */
  268. static struct bitmap *
  269. get_bitmap(psfname, x_scale, y_scale, llx, lly, urx, ury)
  270.   /* 
  271.    * When psfname is interpreted at scale, it'll produce 
  272.    * a bounding box of (llx,lly), (urx,ury).  Scale and (llx,lly),(urx,ury)
  273.    * do not include shrink_factor.  We'll run gs at the same resolution
  274.    * xdvi is running at to take care of shrink_factor.
  275.    */
  276.   char *psfname;
  277.   float x_scale, y_scale;
  278.   int llx, lly, urx, ury;
  279.   int line, status;
  280.   char command[500], tempfilename[L_tmpnam];
  281.   FILE *gs_out;
  282.   char *name;
  283.   struct bitmap *result;
  284.  
  285.   result = find_bitmap(psfname, x_scale, y_scale, RESOLUTION);
  286.   if (result) return result;
  287.  
  288.   /* Build it and they will come. */
  289.  
  290.   name = kpse_path_search (KPSE_TEX_PATH (), psfname);
  291.   if (!name) {
  292.     Moan("Cannot open %s.", psfname);
  293.     return NULL;
  294.   }
  295.  
  296.   result = (struct bitmap *) xmalloc(sizeof(struct bitmap), XMALLOC_LABEL);
  297.   while (!result && cache) {
  298.     flush_one_gsbm();
  299.     result = (struct bitmap *) xmalloc(sizeof(struct bitmap), XMALLOC_LABEL);
  300.   }
  301.   if (!result) {
  302.     Moan("Cannot malloc.", (char*)NULL);
  303.     return NULL;
  304.   }
  305.  
  306.   result->w = (short) PT2PXL(urx-llx+1); /* TODO need to round these up? */
  307.   result->h = (short) PT2PXL(ury-lly+1);
  308.  
  309.   alloc_bitmap(result);
  310.   while (!result->bits && cache) {
  311.     flush_one_gsbm();
  312.     alloc_bitmap(result);
  313.   }
  314.   if (!result->bits) {
  315.     Moan("Cannot malloc", (char*)NULL);
  316.     free(result);
  317.     return NULL;
  318.   }
  319.  
  320.   /* Translate the figure to the bottom left corner (next to the PostScript
  321.    * origin).  Scale as called for by \epsf.  Append a showpage in case the
  322.    * psfile doesn't have one.   Run ghostscript at the same resolution xdvi
  323.    * is running at.  Have ghostscript output a "geometry" (aka 2d matrix of
  324.    * pixels) the same as the bitmap we're after.  Note that ghostscript's bit
  325.    * device driver always right-pads output scan lines to the nearst byte.
  326.    *
  327.    * Even when -q is used, ghostscript yells some error messages to stdout.
  328.    * So we don't write the bitmap to stdout; instead write it to a file  
  329.    * and send stdout and stderr to /dev/null.  (We could use stdout if we'd
  330.    * rewrite gs_fonts.ps et al to strictly obey -q.)
  331.    */
  332.  
  333.   tmpnam(tempfilename);
  334.   sprintf(command, 
  335.       "(echo %d %d translate %f %f scale; cat %s;) | %s -q -sDEVICE=bit -r%d -g%dx%d -sOutputFile=%s -", 
  336.       -llx, -lly, x_scale, y_scale, name, GSEXEC, RESOLUTION,
  337.       (int)result->w, (int)result->h, tempfilename);
  338.  
  339.   status = system(command);
  340.   if (status) {             /* Something went wrong. */
  341.     char buff[256];
  342.     sprintf(buff, "sh command \"%s\" failed with status %d.",
  343.         command, status);
  344.     Moan(buff, (char*)NULL);
  345.     free(result->bits);
  346.     free(result);
  347.     return NULL;
  348.   }
  349.  
  350.   gs_out = fopen(tempfilename, "r");
  351.   if (!gs_out) {
  352.     Moan("Cannot read %s.", tempfilename);
  353.     free(result->bits);
  354.     free(result);
  355.     return NULL;
  356.   }     
  357.  
  358.   {
  359.     int line_size = (int)(ROUNDUP(result->w, 8));
  360.  
  361.     for (line=0; line < ((int)result->h); line++)
  362.       fread(&(result->bits[line*result->bytes_wide]), line_size, 1, gs_out); 
  363.   }
  364.  
  365.   fclose(gs_out);
  366.   unlink(tempfilename);
  367.  
  368.   {  /* The following array used to appear, by another name, in pxl.c.  */
  369.     static  unsigned char reverse_bits[0x100] = { 
  370.         0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
  371.         0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
  372.         0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
  373.         0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
  374.         0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
  375.         0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
  376.         0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
  377.         0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
  378.         0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
  379.         0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
  380.         0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
  381.         0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
  382.         0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
  383.         0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
  384.         0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
  385.         0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
  386.         0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
  387.         0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
  388.         0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
  389.         0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
  390.         0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
  391.         0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
  392.         0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
  393.         0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
  394.         0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
  395.         0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
  396.         0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
  397.         0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
  398.         0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
  399.         0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
  400.         0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
  401.         0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
  402.     };
  403.     int i, max=((int)result->bytes_wide) * ((int)result->h);
  404.  
  405.     for (i=0; i<max; i++)
  406.       result->bits[i] = reverse_bits[(unsigned char)(result->bits[i])];
  407.  
  408. #ifdef SPARC
  409.   {
  410.       int temp;
  411.     /* Sparc machines use a different BYTE ordering.  The code below does
  412.        the appropriate swapping.  In a hacky, crude manner, I admit. 
  413.        Norm 6/7/93
  414.      */
  415.     
  416.     for (i=0; i<max; i += 2)
  417.       {
  418.     temp = result->bits[i];
  419.     result->bits[i] = result->bits[i+1];
  420.     result->bits[i+1] = temp;
  421.       }
  422.  
  423.     for (i=0; i<max; i += 4)
  424.       {
  425.     temp = result->bits[i+0];
  426.     result->bits[i+0] = result->bits[i+2];
  427.     result->bits[i+2] = temp;
  428.  
  429.     temp = result->bits[i+1];
  430.     result->bits[i+1] = result->bits[i+3];
  431.     result->bits[i+3] = temp;
  432.       }
  433.   }
  434. #endif /* SPARC */
  435.  
  436. /* Don't know what you have to do to make this work on a LSB machine.
  437.  * Don't know what gs outputs on LSB, but probably bits in the usual
  438.  * left-right, top-down order.  The above loop switches
  439.  * bit order in each result->bits[] byte.  Might also have to switch
  440.  * byte order in each BYTES_PER_BMUNIT group.
  441.  */
  442.  }
  443.  
  444.  /* Add it to the cache. */
  445.  {struct cache_node *new_head = (struct cache_node *)xmalloc(
  446.                 sizeof(struct cache_node), XMALLOC_LABEL);
  447.   
  448.   if (new_head) {
  449.     new_head->filename   = (char *) xstrdup(psfname);
  450.     new_head->mtime      = mod_time_of(psfname);
  451.     new_head->scale      = x_scale;
  452.     new_head->resolution = RESOLUTION;
  453.     new_head->bm         = result;
  454.     new_head->next       = cache;
  455.     cache = new_head;
  456.   }
  457.  }
  458.  return result;
  459. }
  460.  
  461. /*
  462.  * Execute /special commands of the form 
  463.  *   psfile=/u11/doug/foo.ps llx=165 lly=346 urx=461 ury=434 rwi=2663
  464.  */
  465. void
  466. epsfile(special)
  467.   char *special;
  468. {
  469.   int llx, lly, urx, ury, rwi;
  470.   char psfilename[100];
  471.   float epsf_scale;
  472.   struct bitmap *bitmap;
  473.  
  474.   if (no_epsf) return;
  475.   if (!parse_special(special, psfilename, &llx, &lly, &urx, &ury, &rwi)) 
  476.     return;
  477.  
  478.   /* rwi is 10 times the desired width, in points.  epsf_scale is thus the
  479.    * scale according to the \special command.  (For epsfile.tex specials,
  480.    * x and y scale are always the same.) */
  481.   epsf_scale = (float)(rwi) / 10.0 / (float)(urx-llx+1);
  482.  
  483.   /* 
  484.    * Scale the bounding box.  The floating point calculations have
  485.    * potential round-down errors, so add an extra pixel to compensate. 
  486.    */
  487.   llx = (int) ((float)(llx) * epsf_scale);
  488.   lly = (int) ((float)(lly) * epsf_scale);
  489.   urx = (int) ((float)(urx) * epsf_scale);
  490.   ury = (int) ((float)(ury) * epsf_scale);
  491.   urx++; ury++;
  492.  
  493.   if (epsf_grey) {
  494.     put_grey_rectangle(PXL_H, PXL_V - PT2PXL(ury-lly), 
  495.                PT2PXL(urx-llx+1), PT2PXL(ury-lly+1));
  496.   } else {
  497.     bitmap = get_bitmap(psfilename, epsf_scale, epsf_scale, llx, lly, urx, ury);
  498.     if (bitmap) {
  499.       put_bitmap(bitmap, PXL_H, PXL_V - PT2PXL(ury-lly));
  500.     } else {
  501.       put_grey_rectangle(PXL_H, PXL_V - PT2PXL(ury-lly), 
  502.              PT2PXL(urx-llx+1), PT2PXL(ury-lly+1));
  503.     }
  504.   }
  505. }
  506.  
  507. /*
  508.  * Execute /special commands of the form 
  509.  *   ps::[begin] width height llx lly urx ury ...
  510.  * 
  511.  * where each parameter is in scaled points (65536sp/TeXpt)
  512.  */
  513.  
  514. static int psfig_ok = 0;
  515. static int psfig_llx, psfig_lly, psfig_urx, psfig_ury;
  516. static int psfig_width, psfig_height;
  517.  
  518. void
  519. psfig_setup(special)
  520.   char *special;
  521. {
  522.   if (no_epsf) return;
  523.   psfig_ok = parse_psfig_special(special, &psfig_width, &psfig_height,
  524.                               &psfig_llx, &psfig_lly, 
  525.                               &psfig_urx, &psfig_ury);
  526. }
  527.  
  528. void
  529. psfig(special)
  530.      char *special;
  531. {
  532.   char psfilename[256];
  533.   float x_scale, y_scale;
  534.   struct bitmap *bitmap;
  535.   int llx, lly, urx, ury;
  536.   int width, height;
  537.   int scaled_width, scaled_height;
  538.  
  539.   if (!psfig_ok)
  540.     return;
  541.  
  542.   if (sscanf(special, "ps: plotfile %s ", psfilename) != 1)
  543.     {
  544.       Moan("\"%s\" not understood.", special);
  545.       return;
  546.     }
  547.  
  548.   llx = (int) ((float)(psfig_llx) / 65536.0);
  549.   lly = (int) ((float)(psfig_lly) / 65536.0);
  550.   urx = (int) ((float)(psfig_urx) / 65536.0);
  551.   ury = (int) ((float)(psfig_ury) / 65536.0);
  552.   scaled_width = (int) ((float)(psfig_width) / 65536.0);
  553.   scaled_height = (int) ((float)(psfig_height) / 65536.0);
  554.  
  555.   width = (urx - llx) + 1;
  556.   height = (ury - lly) + 1;
  557.  
  558.   x_scale = ((float)(scaled_width)/(float)(width));
  559.   y_scale = ((float)(scaled_height)/(float)(height));
  560.  
  561.   llx = (int) ((float)(llx) * x_scale);
  562.   lly = (int) ((float)(lly) * y_scale);
  563.   urx = (int) ((float)(urx) * x_scale);
  564.   ury = (int) ((float)(ury) * y_scale);
  565.   urx++; ury++;
  566.  
  567.   if (epsf_grey) {
  568.     put_grey_rectangle(PXL_H, PXL_V,
  569.                PT2PXL(urx-llx+1), PT2PXL(ury-lly+1));
  570.   } else {
  571.     bitmap = get_bitmap(psfilename, x_scale, y_scale, llx, lly, urx, ury);
  572.     if (bitmap) {
  573.       put_bitmap(bitmap, PXL_H, PXL_V);
  574.     } else {
  575.       put_grey_rectangle(PXL_H, PXL_V,
  576.              PT2PXL(urx-llx+1), PT2PXL(ury-lly+1));
  577.     }
  578.   }
  579. }
  580.  
  581.  
  582. Thank you,
  583.  
  584. Francois Magnan
  585.